home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / 1990 / 03 / pat&flen.lst < prev    next >
File List  |  1990-02-13  |  9KB  |  397 lines

  1. MANAGING MULTIPLE DATA SEGMENT UNDER MICROSOFT WINDOWS: PART II
  2. by Tim Paterson and Steve Flenniken
  3.  
  4. [LISTING ONE]
  5.  
  6. [LISTING ONE]
  7.  
  8. /* segments.c */
  9.  
  10. #include <stdio.h> 
  11. #include <stdlib.h> 
  12. #include <windows.h>
  13. #include "segments.h"
  14. #include "segtable.h" 
  15.  
  16. int szAppNameLength = 8;
  17. char *szAppName = "Segments";
  18. char *szClocks = "Too many clocks or timers!";
  19. char *szOutOfMemory = "Not enough memory.";
  20.  
  21. #define MAX_VARIABLE_PSEGS (MAXPSEGS - MINPSEGS - 1)
  22.  
  23. typedef struct data {
  24.     PSEG    pseg; 
  25.     SEG        lastseg; 
  26.     SEG        oldseg; 
  27.     short    changed;
  28. } DATA, FAR * DATAP;
  29.  
  30. PSEG    psegdata;
  31. #define FARDATAP ( (DATAP)FARPTR(0, *psegdata) )
  32.  
  33. short    xchar;
  34. short    ychar;
  35. BOOL    random_action = TRUE;
  36. int        action_count = 0;
  37. HWND    hWindow;
  38.  
  39. PSEG allocate(LONG size, char *string);
  40. BOOL reallocate(PSEG pseg, LONG size, char *string);
  41. LONG FAR PASCAL SegmentsWndProc(HWND, unsigned, WORD, LONG);
  42. int FAR PASCAL timer_routine(HWND hwnd, unsigned message, short id, LONG time);
  43. IFP strcpyifp(IFP string1, IFP string2);
  44. int strlenifp(IFP string);
  45.  
  46. int FAR PASCAL timer_routine(HWND hwnd, unsigned message, short id, LONG time)
  47. {
  48. /* Randomly allocate/free a segment in the Segment Table or
  49. monitor the Segment Table for movement.  Update the line in the window 
  50. that changes.
  51. */
  52.     int        i;
  53.     LONG     size;
  54.     char    buffer[40];
  55.     RECT    rect;
  56.     int        random_switch;
  57. message;
  58. id;
  59. time;
  60.  
  61.     if (random_action)
  62.     {
  63.         if (++action_count < 10)
  64.             return(0);
  65.  
  66.         action_count = 0;
  67.  
  68.         i = rand() % MAX_VARIABLE_PSEGS;
  69.  
  70.         size = (LONG)rand();    /* 0 <= size <= 32767 */
  71.         sprintf(buffer, "  %d bytes", (short)size);
  72.         random_switch = rand();
  73.     
  74.         if (FARDATAP[i].pseg)
  75.         {
  76.             if (random_switch > 2*32767/4)
  77.             {
  78.               if (FARDATAP[i].lastseg == 0)    /* if data is free */
  79.                   FARDATAP[i].changed = -1; /* reset the count */
  80.               buffer[0] = 'R';
  81.               reallocate(FARDATAP[i].pseg, size, buffer);
  82.             }
  83.             else if (random_switch > 1*32767/4)
  84.             {
  85.                 SegmentFree(FARDATAP[i].pseg);
  86.                 FARDATAP[i].pseg = 0;
  87.             }
  88.             else if (*FARDATAP[i].pseg)
  89.                 DataFree(FARDATAP[i].pseg);
  90.         }
  91.         else
  92.         {
  93.             buffer[0] = 'A';
  94.             FARDATAP[i].pseg = allocate(size, buffer);
  95.             FARDATAP[i].changed = -1;
  96.         }
  97.  
  98.         SetRect(&rect, 9*xchar, (i+2)*ychar, 46*xchar, (i+3)*ychar);
  99.         InvalidateRect(hwnd, &rect, TRUE); 
  100.     }
  101.     
  102.     for (i = 0; i < MAX_VARIABLE_PSEGS; i++)
  103.     {
  104.         if (FARDATAP[i].lastseg != *FARDATAP[i].pseg)
  105.         {
  106.          FARDATAP[i].oldseg = FARDATAP[i].lastseg;
  107.          FARDATAP[i].lastseg = *FARDATAP[i].pseg;
  108.          FARDATAP[i].changed++;
  109.          SetRect(&rect, 9*xchar, (i+2)*ychar, 46*xchar, (i+3)*ychar);
  110.          InvalidateRect(hwnd, &rect, TRUE);
  111.         }
  112.     }
  113.     return(0);
  114. }
  115.  
  116. void SegmentsPaint(HDC hDC)
  117. {
  118.     char    buffer[100]; 
  119.     short    len;        
  120.     int        i;
  121.  
  122.     TextOut(hDC, 9*xchar, ychar, "pseg  seg  oldseg moved", 23);
  123.     for (i = 0; i < MAX_VARIABLE_PSEGS; i++)
  124.     {
  125.        len = sprintf(buffer, "data[%d] %.4X  %.4X", i, FARDATAP[i].pseg, *FARDATAP[i].pseg);
  126.         TextOut(hDC, xchar, (i+2)*ychar, buffer, len);
  127.         if (FARDATAP[i].pseg)
  128.         {
  129.            if (*FARDATAP[i].pseg == 0)
  130.            TextOut(hDC, 31*xchar, (i+2)*ychar, "Data Free", 9);
  131.            else
  132.            {
  133.            len = sprintf(buffer, "%.4X  %.2X", FARDATAP[i].oldseg, FARDATAP[i].changed);
  134.               TextOut(hDC, 21*xchar, (i+2)*ychar, buffer, len);
  135.                 strcpyifp(MAKEIFP(buffer, &segDgroup),MAKEIFP(0, FARDATAP[i].pseg));
  136.                 len = strlenifp(MAKEIFP(buffer, &segDgroup));
  137.                   TextOut(hDC, 31*xchar, (i+2)*ychar, buffer, len);
  138.            }
  139.         }
  140.         else
  141.             TextOut(hDC, 31*xchar, (i+2)*ychar, "Free", 4);
  142.     }
  143.  
  144.  }
  145.  
  146. IFP strcpyifp(IFP string1, IFP string2)
  147. {
  148.     char FAR *str1;
  149.     char FAR *str2;
  150.  
  151.     str1 = IFP2PTR(string1);
  152.     str2 = IFP2PTR(string2);
  153.  
  154.     while (1)
  155.     {
  156.         *str1++ = *str2;
  157.         if (*str2 == 0)
  158.             break;
  159.         str2++;
  160.     }
  161.     return(string1);
  162. }
  163.  
  164. int strlenifp(IFP string)
  165. {
  166.     char FAR *str;
  167.     int    len;
  168.  
  169.     str = IFP2PTR(string);
  170.  
  171.     for (len = 0; str[len] != 0; len++)
  172.         ;
  173.     return(len);
  174. }
  175.  
  176. BOOL SegmentsInit(HANDLE hInstance)
  177. {
  178.     WNDCLASS   SegmentsClass;
  179.  
  180.     SegmentsClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  181.     SegmentsClass.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(SEGTABLEICON));
  182.     SegmentsClass.lpszMenuName   = "segmentsmenu";
  183.     SegmentsClass.lpszClassName  = szAppName;
  184.     SegmentsClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  185.     SegmentsClass.hInstance      = hInstance;
  186.     SegmentsClass.style          = CS_HREDRAW | CS_VREDRAW;
  187.     SegmentsClass.lpfnWndProc    = SegmentsWndProc;
  188.  
  189.     if (!RegisterClass((LPWNDCLASS)&SegmentsClass))
  190.         return FALSE;
  191.  
  192.     return TRUE;
  193. }
  194.  
  195. PSEG allocate(LONG size, char *string)
  196. {
  197. /*
  198. Allocate 'size' bytes from the global heap.  Copy a null terminated
  199. 'string' into the allocated memory.
  200. */
  201.     PSEG    pseg;
  202.     char FAR *farptr;
  203.     int        i;
  204.  
  205.     if (!(pseg = SegmentAlloc(size))) 
  206.         return NULL; 
  207.     farptr = FARPTR(0, *pseg);
  208.     for (i = 0; string[i] && i < (int)size-1; i++)
  209.         farptr[i] = string[i];
  210.     farptr[i] = 0;
  211.     return pseg;
  212. }
  213.  
  214. BOOL reallocate(PSEG pseg, LONG size, char *string)
  215. {
  216. /*
  217. Allocate 'size' bytes from the global heap.  Copy a null terminated string 
  218. 'string' into the allocated memory.
  219. */
  220.     char FAR *farptr;
  221.     int        i;
  222.  
  223.     if (!(SegmentRealloc(pseg, size))) 
  224.         return FALSE; 
  225.     farptr = FARPTR(0, *pseg);
  226.     for (i = 0; string[i] && i < (int)size-1; i++)
  227.         farptr[i] = string[i];
  228.     farptr[i] = 0;
  229.     return TRUE;
  230. }
  231.  
  232. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int cmdShow)
  233. {
  234.     MSG   msg;
  235.     HWND  hWnd;
  236.     int   i; 
  237.     TEXTMETRIC tm;
  238.     HDC    hdc;
  239.     FARPROC lpprocTimer;
  240.     DATAP    datap;
  241. lpszCmdLine;
  242.  
  243.     if (!hPrevInstance)
  244.         if (!SegmentsInit(hInstance))
  245.             return FALSE;
  246.  
  247.     SegmentInit();
  248.     if (!(psegdata = SegmentAlloc((DWORD)sizeof(DATA)*MAX_VARIABLE_PSEGS)))
  249.     {
  250.         MessageBox(hWnd, szOutOfMemory, szAppName, MB_OK);
  251.         return FALSE;
  252.     }
  253.  
  254.     datap = FARPTR(0, *psegdata);
  255.     for (i = 0; i < MAX_VARIABLE_PSEGS; i++)
  256.     {
  257.         datap[i].lastseg = 0;
  258.         datap[i].pseg = 0;
  259.     }
  260.  
  261.     hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
  262.     GetTextMetrics(hdc, &tm);
  263.     xchar = tm.tmAveCharWidth;
  264.     ychar = tm.tmHeight;
  265.     DeleteDC(hdc);
  266.  
  267.       hWindow = hWnd = CreateWindow(szAppName, szAppName, WS_TILEDWINDOW, 0, 0,46*xchar, 14*ychar, NULL, NULL, hInstance, NULL);
  268.  
  269.     lpprocTimer = MakeProcInstance(timer_routine, hInstance);
  270.     while (!SetTimer(hWnd, 1, 100, lpprocTimer))
  271.     {
  272.         if (IDCANCEL == MessageBox(hWnd, szClocks, szAppName, MB_ICONEXCLAMATION | MB_RETRYCANCEL))
  273.         return FALSE; 
  274.     }
  275.  
  276.     ShowWindow(hWnd, cmdShow);
  277.     UpdateWindow(hWnd);
  278.  
  279.     while (GetMessage(&msg, NULL, 0, 0))
  280.     {
  281.         TranslateMessage(&msg);
  282.         DispatchMessage(&msg);
  283.     }
  284.  
  285.     return (int)msg.wParam;
  286. }
  287.  
  288. LONG FAR PASCAL SegmentsWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam)
  289. {
  290.     PAINTSTRUCT ps;
  291.  
  292.     switch (message)
  293.     {
  294.         case WM_COMMAND:
  295.             switch (wParam)
  296.             {
  297.                 case MENU_START:
  298.                     random_action = TRUE;
  299.                     break;
  300.                 case MENU_STOP:
  301.                     random_action = FALSE;
  302.                     break;
  303.                 default:
  304.                     break;
  305.             }
  306.             break;
  307.     
  308.         case WM_DESTROY:
  309.             KillTimer(hWnd, 1);
  310.             PostQuitMessage(0);
  311.             break;
  312.     
  313.         case WM_PAINT:
  314.             BeginPaint(hWnd, &ps);
  315.             SegmentsPaint(ps.hdc);
  316.             EndPaint(hWnd, &ps);
  317.             break;
  318.     
  319.         default:
  320.             return DefWindowProc(hWnd, message, wParam, lParam);
  321.             break;
  322.     }
  323.     return(0L);
  324. }
  325.  
  326.  
  327.  
  328. [LISTING TWO]
  329.  
  330. /* segments.h */
  331.  
  332. #define SEGTABLEICON 1
  333. #define MENU_START   50
  334. #define MENU_STOP    51
  335.  
  336.  
  337. [LISTING THREE]
  338.  
  339. # segments.mak
  340.  
  341. cp=cl -d -DDEBUG -c -W2 -DLINT_ARGS -AM -Gswc -Os -Zdpi
  342.  
  343. .c.obj:
  344.     $(cp) $*.c >$*.err
  345.      type $*.err
  346.  
  347. segtable.obj: segtable.c segtable.h
  348.  
  349. segments.obj: segments.c segments.h segtable.h
  350.  
  351. segments.res: segments.rc segments.ico segments.h
  352.     rc -r segments.rc
  353.  
  354. segments.exe: segments.obj segments.res segments.def segtable.obj
  355.   link4 /linenumbers/co segments segtable,/align:16,/map,mlibw/noe,segments.def
  356.   mapsym segments
  357.   rc segments.res
  358.  
  359.  
  360.  
  361. [LISTING FOUR]
  362.  
  363. /* segments.rc */
  364.  
  365. #include "segments.h"
  366.  
  367. SEGTABLEICON  ICON    segments.ico
  368.  
  369. segmentsmenu MENU
  370. BEGIN
  371.     MENUITEM "Start!", MENU_START
  372.     MENUITEM "Stop!", MENU_STOP
  373. END
  374.  
  375.  
  376.  
  377. [LISTING FIVE]
  378.  
  379. ; segments.def
  380.  
  381. NAME    Segments
  382.  
  383. DESCRIPTION 'Segments'
  384.  
  385. STUB    'WINSTUB.EXE'
  386.  
  387. CODE    MOVEABLE
  388. DATA    MOVEABLE MULTIPLE
  389.  
  390. HEAPSIZE  10000
  391. STACKSIZE 4096
  392.  
  393. EXPORTS
  394.     SegmentsWndProc @1
  395.     timer_routine @2
  396.  
  397.